/**************************************************************************************
 *  Copyright (c)  2010  Leszek Karcz, Changmin Bae.
 *  Permission is granted to copy, distribute and/or modify this document
 *  under the terms of the GNU Free Documentation License, Version 1.3
 *  or any later version published by the Free Software Foundation;
 *  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 *  A copy of the license is included in the section entitled "GNU
 *  Free Documentation License". 
 **************************************************************************************/
package data.tileables;
import data.LinkedList;
import data.Map;
import data.Player;
import data.UnitOwner;
import data.missions.*;

/**************************************************************************************
 * Author(s): Leszek Karcz, Changmin Bae
 * Fort building, for creating fighters and defending territory
 **************************************************************************************/
public class Fort extends Structure implements UnitOwner
{
	public static final int [] PRICE = { 30, 30, 10 };
	private int currentRadius;
	private LinkedList<Unit> assignedUnits=new LinkedList<Unit>();	
	
	/**************************************************************************************
	 * Author(s): Eric Martin-Taylor
	 * Removes a unit from the list.
	 * 		True = unit was removed
	 * 		False = unit was in in rally
	 **************************************************************************************/
	public boolean removeUnit(Unit unit)
	{		
		if(this.assignedUnits.remove(unit)==null)
		{
			return false;
		}
		return true;		
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * adds the unit to the list
	 **************************************************************************************/
	public boolean addUnit(Unit unit)
	{		
		if(!this.assignedUnits.find(unit))
		{
			this.assignedUnits.addBack(unit);
			return true;
		}
		return false;
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz, Changmin Bae
	 * Fort constructor
	 **************************************************************************************/
	public Fort(int ID, int supertypeID, Player player, int workers)
	{
		super(ID, supertypeID, player, workers);
		this.setType("Fort");
		this.setImage("struct_fort");
		this.setIcon("struct_fort");
		this.setStats(8, 2.5, 100, 50, 15, 15, 2);
		this.setUpkeep(new int[]{0,2,2});
		this.setNumberOfCommands(4);
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz, Changmin Bae
	 * executes instructions regarding currently selected command
	 **************************************************************************************/
	public boolean enqueueSelectedCommand(String mode, Map m, int x, int y)
	{
		int selected=this.getSelectedCommand();
		if(this.isFinished())
		{
			switch(selected)
			{
				case 0:
					this.die();
				case 1:
					if(this.getState() == 0)
						this.addMission(new PowerUp(this));
					else
						this.addMission(new PowerDown(this));
					break;
				case 2: 
					if(this.getState() == 1)
					{
						this.addMission(new TrainMelee(this, m, player));
					}
					break;
				case 3: 
					if(this.getState() == 1)
					{
						this.addMission(new TrainRanged(this, m, player));
					}
					break;
			}
		}
		else
		{
			switch(selected)
			{
				case 0:
					this.die();
			}
		}	
		
		return true;
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz, Changmin Bae
	 * returns list of possible commands
	 **************************************************************************************/
	public String[] getCommandsText()
	{
		if(this.isFinished())
		{
			return new String[]{"Decommision",(this.getState()==0 ? "Power up" : "Power down"),"Train Melee", "Train Range"};
		}
		else
		{
			return new String[]{"Cancel"};
		}
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * returns bonus
	 **************************************************************************************/
	public int getBonus(int radius)
	{
		if(this.isFinished() && this.getState()==1)
		{
			return this.currentRadius-radius+1;
		}
		else
		{
			return 0;
		}
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * returns offensive damage based on range
	 **************************************************************************************/
	public int getOffensiveDamage(int radius)
	{
		if(this.isFinished() && this.getState()==1)
		{
			if(radius<=this.currentRadius)
			{
				return (int)(this.getStats()[3]+this.getStats()[3]*(1-((double)(radius+1)/this.currentRadius)));
			}
			else
			{
				return 0;
			}			
		}
		else
		{
			return 0;
		}
	}
	
	/**************************************************************************************
	 * Author(s): Leszek Karcz
	 * returns defensive damage based on range
	 **************************************************************************************/
	public int getDefensiveDamage(int radius)
	{
		if(this.isFinished() && this.getState()==1)
		{
			if(radius<=this.currentRadius)
			{
				return (int)(this.getStats()[4]+this.getStats()[4]*(1-((double)(radius+1)/this.currentRadius)));
			}
			else
			{
				return 0;
			}			
		}
		else
		{
			return 0;
		}
	}
	
	/**************************************************************************************
	 * Author(s): Pablo Echeverri, Changmin Bae
	 * overrides superclass execute to add adding of area bonus
	 **************************************************************************************/
	public void execute()
	{
		super.execute();
		//building process will be handled by workers 
		if(this.isFinished())
		{
			int radiusTech=this.player.getTechnology("Fort", "Visibility Radius");
			if((radiusTech+this.getVisionRadius())!= this.currentRadius)
			{
				this.currentRadius=radiusTech+this.getVisionRadius();
				this.player.addFortAreaBonus(this, this.currentRadius);
			}

			if(this.getState()==1)
			{
				this.player.attackArea(this.getX(), this.getY(), this, this.currentRadius);
			}
		}
		
	}
	@Override
	public void die()
	{ 
		super.die();
		player.removeFort(this);
	}
}
